/**
 * PNotaDespesa.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package persistencia.notas;

import java.io.IOException;
import negocio.notas.NotaDespesa;
import java.sql.*;
import plagio.postgres.ConnectionPostgres;
import java.util.*;
import utils.*;

/**
 *
 * @author jmsandy
 */
public class PNotaDespesa extends PNota{

    //<editor-fold defaultstate="collapsed" desc="Attributes">
    private boolean error = false;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Acessores">
    public boolean isError(){
        return this.error;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Table Columns">
    static final protected String K_COL_despesa = "despesa";
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    /**
     * Construtor padrao. Responsavel por realizar a persistencia de uma
     * nota de despesa.
     * @throws java.io.IOException
     */
    public PNotaDespesa() throws IOException{
        error = false;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Methods">
    // Realiza a construcao basica de um select
    private StringBuilder formSelector(){
        StringBuilder query = new StringBuilder();
        query.append("SELECT " + K_COL_cod_objeto + ", " + K_COL_classname);
        query.append(", " + K_COL_numNota + ", " + K_COL_serie + ", ");
        query.append(K_COL_dtEmissao + ", " + K_COL_dtEntrada + ", ");
        query.append(K_COL_valorNota + ", " + K_COL_situacao + ", ");
        query.append(K_COL_fornecedor + ", " + K_COL_empreendimento + ", ");
        query.append(K_COL_despesa + " FROM \"" + K_TBL_Nota + "\"");
        return query;
    }

    /**
     * Responsavel por criar a estrutura para inserir o objeto
     * @return construtor do objeto a ser inserido
     */
    private String formInsert(){
        return "INSERT INTO \"" + K_TBL_Nota + "\"(" + K_COL_cod_objeto +
           ", " + K_COL_classname + ", " + K_COL_numNota + ", " + K_COL_serie +
           ", " + K_COL_dtEmissao + ", " + K_COL_dtEntrada + ", " +
           K_COL_valorNota + ", " + K_COL_situacao + ", "  + K_COL_fornecedor +
           ", " + K_COL_empreendimento + "," + K_COL_despesa +
           ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
    }

    /**
     * Responsavel por criar a estrutura para atualizar o objeto
     * @param obj - Objeto a ser atualizado na base de dados
     * @return construtor do objeto a ser atualizado
     */
    private String formUpdate(NotaDespesa obj){
        StringBuilder query = new StringBuilder();
        query.append("UPDATE \"" + K_TBL_Nota + "\" SET ");
        query.append(K_COL_numNota + " = '" + obj.getNumNota() + "', ");
        query.append(K_COL_serie + " = '" + obj.getSerie() + "', ");
        query.append(K_COL_valorNota + " = '" + obj.getValorNota() + "', ");
        query.append(K_COL_situacao + " = '" + obj.getSituacao() + "', ");
        query.append(K_COL_fornecedor + " = '" + obj.getFornecedor() + "', ");
        query.append(K_COL_empreendimento+" = '"+obj.getEmpreendimento());
        query.append("', " + K_COL_despesa + " = '" + obj.getDespesa() + "'");
        query.append(obj.getDtEmisao() != null ? (" , " +
                    K_COL_dtEmissao + " = '"  + obj.getDtEmisao() + "'"):"");
        query.append(obj.getDtEntrada() != null ? (" , " +
                  K_COL_dtEntrada + " = '"  + obj.getDtEntrada() + "'"):"");
        query.append(" WHERE " + K_COL_cod_objeto + " = '" +
                                        obj.getCod_objeto() + "'");
        return query.toString();
    }

    /**
     * Responsavel por inserir um objeto na base de dados
     * @param obj - objeto a ser inserido na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean insert(NotaDespesa obj){
        Boolean status = true;

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao
            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();
            PreparedStatement stat;
            String query = formInsert();
            stat = conn.getConnection().prepareStatement(query);
            stat.setString(1, obj.getCod_objeto());
            stat.setString(2, obj.getClassName());
            stat.setInt(3, obj.getNumNota());
            stat.setString(4, obj.getSerie());
            stat.setDate(5, (obj.getDtEmisao() != null ?
                new java.sql.Date(obj.getDtEmisao().getTime()) : null));
            stat.setDate(6, (obj.getDtEntrada() != null ?
                     new java.sql.Date(obj.getDtEntrada().getTime()) : null));
            stat.setDouble(7, obj.getValorNota());
            stat.setInt(8, utils.StatusNota.PENDENTE);
            stat.setString(9, obj.getFornecedor());
            stat.setString(10, obj.getEmpreendimento());
            stat.setString(11, obj.getDespesa());
            stat.executeUpdate();
            stat.close();
            conn.closeConnection();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        return status;
    }

    /**
     * Responsavel por atualizar um objeto na base de dados
     * @param obj - objeto a ser atualizado na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean update(NotaDespesa obj){
        Boolean status = true;

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            // Monta o objeto em uma instrucao SQL para atualizacao no banco
            PreparedStatement stat;
            String query = formUpdate(obj);
            stat = conn.getConnection().prepareStatement(query);
            stat.executeUpdate();
            stat.close();
            conn.closeConnection();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        return status;
    }

    /**
     * Responsavel por recuperar uma lista de todos os objetos que satisfacam
     * as condicoes recebidas para o objeto
     * @param nota: caracteristicas da nota a ser produrado
     * @return lista contendo todos os objetos recuperados
     */
    public ArrayList<NotaDespesa> recLstNotasDespesas(NotaDespesa nota){
        // Lista de objetos de retorno
        ArrayList<NotaDespesa> lstNotas = new ArrayList<NotaDespesa>();
        StringBuilder query = this.formSelector();
        StringBuilder crit  = new StringBuilder();

        // Verifica se foi informado um numero de nota para busca
        if(nota.getNumNota() != null){
            crit.append(" AND " + K_COL_numNota + " = '" +
                                                       nota.getNumNota() + "'");
        }
        // Verifica se foi informada uma serie
        if(nota.getSerie() != null && nota.getSerie().length() > 0){
            crit.append(" AND " + K_COL_serie + " = '" + nota.getSerie() + "'");
        }
        // Verifica se foi informada uma data de emissao
        if(nota.getDtEmisao() != null){
            crit.append(" AND " + K_COL_dtEmissao + " = '" +
                                                      nota.getDtEmisao() + "'");
        }
        // Verifica se foi informada uma data de entrada
        if(nota.getDtEntrada() != null){
            crit.append(" AND " + K_COL_dtEntrada + " = '" +
                                                     nota.getDtEntrada() + "'");
        }
        // Verifica se foi informada um valor de nota
        if(nota.getValorNota() > 0){
            crit.append(" AND " + K_COL_valorNota + " = '" +
                                                     nota.getValorNota() + "'");
        }
        // Verifica se foi informada uma situacao
        if(nota.getSituacao() != null){
            crit.append(" AND " + K_COL_situacao + " = '" +
                                                      nota.getSituacao() + "'");
        }
        // Verifica se foi informada um fornecedor
        if(nota.getFornecedor() != null && nota.getFornecedor().length() > 0){
            crit.append(" AND " + K_COL_fornecedor + " = '" +
                                                    nota.getFornecedor() + "'");
        }
        // Verifica se foi informada um empreendimento
        if(nota.getEmpreendimento() != null &&
                                        nota.getEmpreendimento().length() > 0){
            crit.append(" AND " + K_COL_empreendimento + " = '" +
                                                nota.getEmpreendimento() + "'");
        }
        // Verifica se foi informada uma despesa
        if(nota.getDespesa() != null && nota.getDespesa().length() > 0){
            crit.append(" AND " + K_COL_despesa + " = '" +
                                                      nota.getDespesa() + "'");
        }
        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            Statement stat = conn.getConnection().createStatement();

            if(crit.toString().startsWith(" AND ")){
                query.append(" WHERE " + K_COL_classname + " = '");
                query.append((new NotaDespesa()).getClassName() + "'");
                query.append(crit.toString());
                lstNotas =  mapear(stat.executeQuery(query.toString()));
            }
            else{
                lstNotas = null;
            }
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            lstNotas = null;
        }
        return lstNotas;
    }

    /**
     * Responsavel por converter o objeto vindo do banco de dados para um
     * modelo de objeto
     * @param result - result que obtem toda lista recebida do servidor
     * @return os objetos mapeados
     * @throws java.sql.SQLException
     */
    private ArrayList<NotaDespesa> mapear(ResultSet result) throws SQLException{
        ArrayList<NotaDespesa> lstNotas = new ArrayList<NotaDespesa>();

        // Converte todo result recebido para uma lista de objetos
        while(result.next()){
            NotaDespesa nota = new NotaDespesa();
            nota.setCod_objeto(result.getString(1));
            nota.setNumNota(result.getInt(3));
            nota.setSerie(result.getString(4));
            nota.setDtEmissao(result.getDate(5));
            nota.setDtEntrada(result.getDate(6));
            nota.setValorNota(result.getDouble(7));
            nota.setSituacao(result.getInt(8));
            nota.setFornecedor(result.getString(9));
            nota.setEmpreendimento(result.getString(10));
            nota.setDespesa(result.getString(11));

            nota.setIsNew(false);

            lstNotas.add(nota);
        }
        return lstNotas;
    }
    //</editor-fold>
}